import { useMemo, useState } from 'react'
import { useEffect } from 'react'
import MemoVsCallback from '../components/render-demo/MemoVsuseCallback'

/**
 *
 * useMemo的用处
 * 返回回调函数的返回值
 * 回调函数没有参数
 * 依赖关系数组必须写一个值, 而且不能是空数组
 * 如果依赖关系是空数组或者null或者undefined都没有意义, 会导致回调函数每次都执行
 * 只缓存最后一次的结果  -- 对比最后一次和上一次依赖关系有没有改变
 * 你应该用useMemo去优化计算结果, 但react不保证useMemo的结果一定来自于上一次缓存(依赖没有变得情况下)
 *
 * useCallback
 * ```js
 * const handleClick = useCallback((e)=>{
 *  console.log(number)
 * },[number])
 *
 * ```
 * 返回一个函数
 * 回调函数可以有参数
 * 只要依赖关系不变, 它返回的函数始终是同一个引用
 * 原生html的react元素上的回调方法不需要用useCallback优化
 * 用在自定义的子组件上(使子组件获得的回调方法每次都是同一个值)
 *
 * 总结
 * useMemo(()=>复杂函数(a,b),[a,b]) 作用是使复杂函数的调用结果可以被缓存, 减少不必要的运算
 * useCallback是useMemo的特殊版本。
 *
 * ```js
 * const handleClick = useMemo(()=>(e)=>{...},[...])
 * // 等同于
 * const handleClick = useCallback((e)=>{...},[...])
 * ```
 */

const MemoAndCallbackDemo = () => {
  console.log('render')
  const [count, setCount] = useState(0)
  useEffect(() => {
    return () => {}
  }, [count])

  const computeWordCount = (words) => {
    let i = 0
    while (i < 10 ** 1) i++
    return words.length
  }
  const [words, setWords] = useState(['hello', 'world', '你好'])
  const wordCount = useMemo(() => {
    console.log('memo run')
    return computeWordCount(words)
  }, [words, count])

  return (
    <>
      词语个数: {wordCount}
      <button onClick={() => setCount(count + 1)}>add:{count}</button>
      <button onClick={() => setCount(count + -1)}>sub:{count}</button>
      <hr />
      <MemoVsCallback />
    </>
  )
}

export default MemoAndCallbackDemo
